package scene

import (
	"cgs-server/helper"
	"cgs-server/server"
	"cgs-server/server/base"
	"fmt"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"net/http"
	"strconv"
	"strings"
)


func init() {
	server.Handle(http.MethodPost, "/api/Scene/Export", ExportScene, server.None)
	server.Post("/api/Scene/Save", Save, "保存场景", server.Login)
	server.Post("/api/Scene/Edit", Edit, "更新场景", server.Login)
	server.Get("/api/Scene/List", List, "获取列表", server.Login)
	server.Get("/api/Scene/LoadByProjectId", LoadByProjectId, "通过ProjectId获取场景数据", server.None)
	server.Get("/api/Scene/Get", GetBySceneId, "获取单个场景信息", server.None)
}

func ExportScene(w http.ResponseWriter, r *http.Request) {
	id := strings.TrimSpace(r.FormValue("ProjId"))
	projectId, err := primitive.ObjectIDFromHex(id)
	if err != nil {
		helper.WriteJSON(w, server.Result{
			Code: 300,
			Msg:  "ID is not allowed.",
		})
		return
	}
	SceneService := NewSceneService()
	zipData, err := SceneService.Export(projectId)
	if err != nil {
		helper.WriteJSON(w, server.Result{
			Code: 300,
			Msg:  err.Error(),
		})
		return
	}
	buf, err := base.ZipFile(zipData)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.CgsResult{
			Code: 300,
			Msg:  err.Error(),
		})
		return
	}
	n, _ := buf.WriteTo(w)

	fmt.Println("字节数：", n)
}

func Save(w http.ResponseWriter, r *http.Request) {

	scene := &Model{}
	name := strings.TrimSpace(r.FormValue("Name"))

	err := helper.ReadRequestBody(&scene, w, r)

	if err != nil || scene.Name == "" {
		if name == "" {
			_, _ = helper.WriteJSON(w, server.Fail("Name is not allowed to be empty."))
			return
		}
		if strings.HasPrefix(name, "_") {
			_, _ = helper.WriteJSON(w, server.Fail("Name is not allowed to start with _."))
			return
		}
		data := strings.TrimSpace(r.FormValue("Data"))

		scene = &Model{
			Name: name,
			Data: data,
		}
		if r.FormValue("ID") != "" {
			id, err := primitive.ObjectIDFromHex(strings.TrimSpace(r.FormValue("ID")))
			if err != nil {
				_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
				return
			}
			scene.ID = id
		}
	}

	dataUserModel := base.GenerateDataUserModel(scene, r)
	sceneService := NewSceneService()
	err = sceneService.Save(dataUserModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}

	result := saveResult{}
	result.Code = 200
	result.Msg = "Saved successfully!"
	result.ID = scene.ID.Hex()
	_, _ = helper.WriteJSON(w, result)
}

func Edit(w http.ResponseWriter, r *http.Request) {
	id, err := primitive.ObjectIDFromHex(strings.TrimSpace(r.FormValue("ID")))
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail("ID is not allowed."))
	}

	name := strings.TrimSpace(r.FormValue("Name"))
	if name == "" {
		_, _ = helper.WriteJSON(w, server.Fail("Name is not allowed to be empty."))
		return
	}
	if strings.HasPrefix(name, "_") {
		_, _ = helper.WriteJSON(w, server.Fail("Name is not allowed to start with _."))
		return
	}

	thumbnail := strings.TrimSpace(r.FormValue("Image"))
	cty := strings.TrimSpace(r.FormValue("Category"))
	isPublic := strings.TrimSpace(r.FormValue("IsPublic"))
	_isPublic := isPublic == "true"
	pinyin := helper.ConvertToPinYin(name)
	scene := &Model{
		ID:          id,
		Name:        name,
		CategoryID:  cty,
		Thumbnail:   thumbnail,
		IsPublic:    &_isPublic,
		TotalPinYin: pinyin.TotalPinYin,
		FirstPinYin: pinyin.FirstPinYin,
	}
	dataUserModel := base.GenerateDataUserModel(scene, r)
	sceneService := NewSceneService()
	err = sceneService.Update(dataUserModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}

	_, _ = helper.WriteJSON(w, server.Result{
		Code: 200,
		Msg:  "Saved successfully!",
	})
}

func List(w http.ResponseWriter, r *http.Request) {
	dataUserModel := base.GenerateDataUserModel(&Model{}, r)
	sceneService := NewSceneService()
	list, err := sceneService.List(dataUserModel)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	if list == nil {
		list = []*Model{}
	}
	_, _ = helper.WriteJSON(w, server.Result{
		Code: 200,
		Msg:  "Get Successfully!",
		Data: list,
	})
}

func LoadByProjectId(w http.ResponseWriter, r *http.Request) {
	id := strings.TrimSpace(r.FormValue("projectId"))
	if id == "" {
		_, _ = helper.WriteJSON(w, server.Result{
			Code: 300,
			Msg:  "ID is not allowed empty.",
		})
	}
	version := -1
	if _version, err := strconv.Atoi(strings.TrimSpace(r.FormValue("version"))); err == nil {
		version = _version
	}

	user, err := base.GetCurrentUser(r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Result{
			Code: 300,
			Msg:  "Permission denied.",
		})
		return
	}

	sceneService := NewSceneService()
	docs, err := sceneService.GetSceneDataByProjectId(id, version, user)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Result{
			Code: 300,
			Msg:  err.Error(),
		})
		return
	}

	helper.WriteJSON(w, server.Result{
		Code: 200,
		Msg:  "Get Successfully!",
		Data: docs,
	})
}

func GetBySceneId(w http.ResponseWriter, r *http.Request) {
	sceneId, err := primitive.ObjectIDFromHex(r.FormValue("sceneId"))
	if err != nil {
		helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}

	sceneModel := &Model{
		ID: sceneId,
	}
	duModel := base.GenerateDataUserModel(sceneModel, r)
	sceneService := NewSceneService()
	one, err := sceneService.GetOne(duModel)
	if err != nil {
		helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	if one == nil {
		helper.WriteJSON(w, server.Fail("Scene is not found."))
		return
	}
	helper.WriteJSON(w, server.OK().WithData(one))
}
